import { getConfig } from '@/config'
import { useDictStoreHook } from '@/store/modules/dict'
import { useMultiTabStore } from '@/store/modules/multiTab'
import { usePermissionStoreHook } from '@/store/modules/permission'
import { useUserStoreHook } from '@/store/modules/user'
import NProgress from '@/utils/progress'
import '@/utils/sso'
// import { useApplyStoreHook } from "@/store/modules/apply";
import { getToken } from '@/utils/auth'
import { buildHierarchyTree } from '@/utils/tree'
import { isUrl, openLink } from '@pureadmin/utils'
import { createRouter, type RouteComponent, type Router, type RouteRecordRaw } from 'vue-router'
import {
  findRouteByPath,
  flattenRoutes,
  formatTwoStageRoutes,
  getHistoryMode,
  handleCacheRoute,
  initRouter,
  sortByRankAsc,
} from './utils'

import { isEmpty } from 'lodash-es'
import remainingRouter from './modules/remaining'

/** 自动导入全部静态路由，无需再手动引入！匹配 src/router/modules 目录（任何嵌套级别）中具有 .ts 扩展名的所有文件，除了 remaining.ts 文件
 * 如何匹配所有文件请看：https://github.com/mrmlnc/fast-glob#basic-syntax
 * 如何排除文件请看：https://cn.vitejs.dev/guide/features.html#negative-patterns
 */
const modules: Record<string, any> = import.meta.glob(
  ['./modules/**/*.ts', '!./modules/**/remaining.ts'],
  {
    eager: true,
  }
)

/** 原始静态路由（未做任何处理） */
const routes = []

Object.keys(modules).forEach((key) => {
  routes.push(modules[key].default)
})

/** 导出处理后的静态路由（三级及以上的路由全部拍成二级） */
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
  flattenRoutes(buildHierarchyTree(sortByRankAsc(routes)))
)

/** 用于渲染菜单，保持原始层级 */
export const constantMenus: Array<RouteComponent> = sortByRankAsc(routes).concat(...remainingRouter)

/** 不参与菜单的路由 */
export const remainingPaths = Object.keys(remainingRouter).map((v) => {
  return remainingRouter[v].path
})

/** 创建路由实例 */
export const router: Router = createRouter({
  history: getHistoryMode(),
  routes: constantRoutes.concat(...(remainingRouter as any)),
  strict: true,
  scrollBehavior(to, from, savedPosition) {
    return new Promise((resolve) => {
      if (savedPosition) {
        return savedPosition
      } else {
        if (from.meta.saveSrollTop) {
          const top: number = document.documentElement.scrollTop || document.body.scrollTop
          resolve({ left: 0, top })
        }
      }
    })
  },
})

/** 重置路由 */
export function resetRouter() {
  router.getRoutes().forEach((route) => {
    const { name, meta } = route
    if (name && router.hasRoute(name) && meta?.backstage) {
      router.removeRoute(name)
      router.options.routes = formatTwoStageRoutes(
        flattenRoutes(buildHierarchyTree(sortByRankAsc(routes)))
      )
    }
  })
  usePermissionStoreHook().clearAllCachePage()
}

/** 路由白名单 */
const whiteList = ['/login', '/welcome', '/trial']

router.beforeEach(async (toRoute, fromRoute) => {
  /**
   * 处理缓存路由
   */
  if (toRoute.meta?.keepAlive) {
    const toMatched = toRoute.matched
    handleCacheRoute(toMatched, 'add')
    // 如果是路由/页面刷新
    if (fromRoute.name === undefined || fromRoute.name === 'Redirect') {
      handleCacheRoute(toMatched)
    }
  }

  NProgress.start()

  /**
   * 外链处理
   */
  const externalLink = isUrl(toRoute?.name as string)
  if (externalLink) {
    openLink(toRoute?.name as string)
    NProgress.done()
    return
  }

  /**
   * 设置浏览器标题
   */
  toRoute.matched.forEach((item) => {
    if (!item.meta.title) return

    const title = getConfig().Title
    if (title) document.title = `${item.meta.title} | ${title}`
    else document.title = item.meta.title as string
  })

  /**
   * 如果用户没有登录，且要导航的页面不在白名单范围内，强制跳转到登录页
   */
  const token = getToken()
  if (!token) {
    if (!whiteList.includes(toRoute.path) && toRoute.path !== '/login') {
      return '/login'
    } else if (toRoute.path === '/welcome') {
      await useDictStoreHook().initDict()
    }
    return
  }

  /**
   * 加载用户、字典信息
   */
  if (isEmpty(useUserStoreHook().roles)) {
    await useUserStoreHook()
      .getInfo()
      .then(() => useDictStoreHook().initDict())
      .catch(() => {
        useUserStoreHook().logOut()
      })
  }

  // 菜单触发的跳转
  if (fromRoute?.name) {
    return
  }

  // 刷新或首次打开页面
  if (isEmpty(usePermissionStoreHook().wholeMenus) && toRoute.path !== '/login') {
    await initRouter().then((router: Router) => {
      if (!useMultiTabStore().enableMultiTabsCache) {
        const { path } = toRoute
        const route = findRouteByPath(path, router.options.routes[0].children)

        if (route && route.meta?.title) {
          useMultiTabStore().pushTab({
            path: route.path,
            name: route.name,
            meta: route.meta,
          })
        }
      }
    })
    return toRoute.fullPath
  }
  return
})

router.afterEach(() => {
  NProgress.done()
})

export default router
